package com.woniuxy.enjoylife.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.woniuxy.enjoylife.entity.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.enjoylife.entity.dto.*;
import com.woniuxy.enjoylife.mapper.CommunityMapper;
import com.woniuxy.enjoylife.mapper.SuggestMapper;
import com.woniuxy.enjoylife.mapper.UserMapper;
import com.woniuxy.enjoylife.service.UserService;
import com.woniuxy.enjoylife.utils.*;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author teamEnjoyLife75
 * @since 2021-01-18
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    UserMapper userMapper;
    @Autowired
    SuggestMapper suggestMapper;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private CommunityMapper communityMapper;

    @Override
    public List<User> findAll() {
        return userMapper.findAll();
    }

    /**
     * 登录
     *
     * @param account
     * @param pwd
     * @return
     */
    @Override
    public User findByAccountPwd(String account, String pwd) {
        Map<String, Object> map = new HashMap<>();
        map.put("account", account);
        map.put("password", pwd);
        map.put("status",0);
        List<User> userList = userMapper.selectByMap(map);
        if (userList.size() > 0) {
            //存取userid的逻辑
            User user = userList.get(0);
            int userId= user.getId();

            String uuid = UUID.randomUUID().toString();

            redisTemplate.opsForValue().set(uuid,userId);
            redisTemplate.expire(uuid, 7l, TimeUnit.DAYS);



            return userList.get(0);
        } else {
            return null;
        }
    }


    /**
     * 用户修改密码
     *
     * @param id
     * @param pwd
     * @return
     */
    @Override
    public int updatePwd(int id, String pwd) {
        return userMapper.updatePwd(id, pwd);
    }

    /**
     * 用户通过邮箱修改密码
     * @param pwd
     * @param code
     * @return
     */
    @Override
    public Boolean updataByEmail(String pwd, String code,String email) {
        //得到对应的key
        String key = RedisKeyGenerator.generate("codes", "sendCode", email);
        //通过key查询验证码
        String code2 = (String) redisTemplate.opsForValue().get(key);
        if (code2 != null && code2.equals(code)) {
            redisTemplate.delete(key);
            //验证码正确,并且没有过期时
            //加密新密码
            pwd = DigestUtils.md5DigestAsHex(pwd.getBytes());
            //修改为新密码
            return userMapper.updatePwdByEmail(email,pwd)>0;
        }else{
            //验证码错误
            return false;
        }
    }

    /**
     * 用户修改昵称
     *
     * @param id
     * @param account
     * @return
     */
    @Override
    public int updateAccount(int id, String account) {
        return userMapper.updateAccount(id, account);
    }

    /**
     * 用户修改头像
     *
     * @param id
     * @param img
     * @return
     */
    @Override
    public int updateHead(int id, String img) {
        return userMapper.updateHead(id, img);
    }

    /**
     * 查询用户基本信息+房屋信息
     *
     * @param id
     * @return
     */
    @Override
    public UserDto findDetail(int id) {
        return userMapper.findDetail(id);
    }


    /**
     * 用户投诉
     *
     * @param suggest
     * @return
     */
    @Override
    public int userSuggest(Suggest suggest) {
        return suggestMapper.insert(suggest);
    }

    /**
     * 通过用户account找到用户
     *
     * @param account
     * @return
     */
    @Override
    public boolean findByAccount(String account) {
        Map<String, Object> map = new HashMap<>();
        map.put("account", account);
        List<User> userList = userMapper.selectByMap(map);
        if (userList.size() > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 通过邮箱找用户
     *
     * @param email
     * @return
     */
    @Override
    public boolean findByEmail(String email) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("email", email);
        List<User> userList = userMapper.selectList(wrapper);
        if (userList.size() > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 用户注册
     *
     * @param user
     * @return
     */
    @Override
    public boolean register(User user, String code,String role) {
        //得到对应的key
        String key = RedisKeyGenerator.generate("codes", "sendCode", user.getEmail());
        //通过key查询验证码
        String code2 = (String) redisTemplate.opsForValue().get(key);
        if (code2 != null && code2.equals(code)) {
            //验证码正确,并且没有过期时
            if (user.getAccount() == null || user.getAccount() == "" || this.findByAccount(user.getAccount())) {
                return false;
            } else if (user.getPassword() == null || user.getPassword() == "") {
                return false;
            } else if (user.getEmail() == null || user.getEmail() == "") {
                return false;
            } else {
                //密码加密
                user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
                //添加到用户表
                if (role.equals("用户")){
                    //是用户注册，直接激活
                    user.setStatus(0);
                    userMapper.addUser(user);
                    userMapper.addUserRole(user.getId(),5);
                }else{
                    //是商户注册，不激活
                    user.setStatus(1);
                    userMapper.addUser(user);
                    userMapper.addUserRole(user.getId(),4);
                    //加入商户注册申请表
                    userMapper.addNewMerchant(user.getId());
                }
                redisTemplate.delete(key);
                return true;
            }
        } else {
            //验证码不正确时
            return false;
        }
    }

    /**
     * 给邮箱发送验证码
     *
     * @param email
     * @return
     */
    @Override
    public boolean sendCode(String email,int type) {
        //创建验证码
        String code = CodeCreate.createCode(5);
        //将验证码放入redis，并设置过期时间
        //设置key
        String key = RedisKeyGenerator.generate("codes", "sendCode", email);
        //放入redis
        redisTemplate.opsForValue().set(key, code);
        //设置过期时间
        redisTemplate.expire(key, 60l, TimeUnit.SECONDS);
        //发送邮件
        if (EmailUtil.send(email, code,type)) {
            return true;
        } else {
            //清除redis数据
            redisTemplate.delete(key);
            return false;
        }
    }

    /**
     * 检查物业账户注册是否可用
     *
     * @param account
     * @return
     */
    @Override
    public boolean checkVillage(String account) {
        //通过用户名查询用户
        User user = userMapper.findUserByAccount(account);
        if (user == null) {
            //没有此用户，不可注册
            return false;
        } else {
            //有此用户，检查用户角色是不是物业
            String name = userMapper.findUsersRole(user.getId());
            if (name != null && name.equals("物管")) {
                //角色是物业
                //检查该物业账号是否已经注册过
                if (communityMapper.findByUserId(user.getId()) == null) {
                    //没注册过
                    return true;
                } else {
                    //注册过
                    return false;
                }
            } else {
                //角色不是物业，不可以注册
                return false;
            }
        }
    }

    /**
     * 进行物业注册
     *
     * @param propertyDto
     * @return
     */
    @Override
    public boolean registerProperty(PropertyDto propertyDto) {
        //通过物业用户名，找到用户id
        User user = userMapper.findUserByAccount(propertyDto.getAccount());
        //查小区名，是否存在
        Community community = communityMapper.haveCommunityByName(propertyDto.getCommunity());
        if (community == null) {
            //没有记录过小区，直接添加信息
            //添加物业注册
            if (communityMapper.registerProperty(propertyDto.getCommunity(), user.getId()) > 0) {
                //注册成功
                return true;
            } else {
                //注册失败
                return false;
            }
        } else {
            //有小区记录，按小区id添加信息
            if (communityMapper.registerPropertyById(community.getId(), user.getId()) > 0) {
                //注册成功
                return true;
            } else {
                //注册失败
                return false;
            }
        }

    }

    /**
     * 平台用户管理信息
     *
     * @param type
     * @return
     */
    @Override
    public PageResult<UserInfoDto> usersInfo(int type, int size, int currentPage) {
        PageResult<UserInfoDto> pageResult = new PageResult<>();
        //分页插件，会自动查询时进行分页并将分页信息封装到recentPage内
        Page<UserInfoDto> userInfoDtoPage = PageHelper.startPage(currentPage, size);

        //根据查询分类，进行查询
        if (type == 0) {
            //type=0 不分类查询
            userMapper.usersInfoAll();
            List<UserInfoDto> userInfoDtoList0 = new ArrayList<>(userInfoDtoPage);
            pageResult.setCurrentPage(currentPage);
            pageResult.setPageSize(size);
            pageResult.setTotal(userInfoDtoPage.getTotal());
            pageResult.setTotalPage(userInfoDtoPage.getPages());
            pageResult.setData(userInfoDtoList0);
        } else if (type != -1) {
            //有角色，可以分类查
            userMapper.usersInfo(type);
            List<UserInfoDto> userInfoDtoList1 = new ArrayList<>(userInfoDtoPage);
            pageResult.setCurrentPage(currentPage);
            pageResult.setPageSize(size);
            pageResult.setTotal(userInfoDtoPage.getTotal());
            pageResult.setTotalPage(userInfoDtoPage.getPages());
            pageResult.setData(userInfoDtoList1);
        } else {
            //查没有角色
            userMapper.usersInfoNoRole();
            List<UserInfoDto> userInfoDtoList2 = new ArrayList<>(userInfoDtoPage);
            pageResult.setCurrentPage(currentPage);
            pageResult.setPageSize(size);
            pageResult.setTotal(userInfoDtoPage.getTotal());
            pageResult.setTotalPage(userInfoDtoPage.getPages());
            pageResult.setData(userInfoDtoList2);
        }
        return pageResult;
    }

    /**
     * 平台用户状态切换
     * @param user
     * @return
     */
    @Override
    public boolean userSwitch(User user) {
        return userMapper.userSwitch(user.getId(),user.getStatus())>0;
    }

    /**
     * 平台用户信息更改
     * @param userInfoDto
     * @return
     */
    @Override
    public boolean userInfoChange(UserInfoDto userInfoDto) {
        //1.检查用户名是否重复
        User userAccount = userMapper.findUserByAccount(userInfoDto.getAccount());
        User userEmail = userMapper.findUserByEmail(userInfoDto.getEmail());
        if(userAccount != null && userAccount.getId() != userInfoDto.getId()){
            return false;
        }
        //2.检查邮箱是否重复
        else if(userEmail != null && userEmail.getId() != userInfoDto.getId()){
            return false;
        }else{
            //3.更新所有信息

            userMapper.updateAccount(userInfoDto.getId(), userInfoDto.getAccount());
            userMapper.userRoleChange(userInfoDto.getId(),userInfoDto.getRole());
            userMapper.updateEmailById(userInfoDto.getId(),userInfoDto.getEmail());
            //房屋id列表
            List<Integer> ids = new ArrayList<>();
            userInfoDto.getUserHouseDtoList().forEach(e->ids.add(e.getId()));
            if(ids.size() != 0){
                //删除多余房屋
                userMapper.delHouseById(ids,userInfoDto.getId());
            }else{
                //删除所有房屋
                userMapper.delHouseAll(userInfoDto.getId());
            }
            //修改房屋信息
            for(UserHouseDto houseDto:userInfoDto.getUserHouseDtoList()){
                System.out.println(houseDto);
                userMapper.updateHouseInfo(houseDto);
            }
            return true;
        }
    }

    /**
     * 平台商家申请列表
     * @return
     */
    @Override
    public List<User> findApply() {
        List<User> userList = userMapper.findApply();
        return userList;
    }

    /**
     * 获取用户头像和昵称
     * @param id
     * @return
     */
    @Override
    public HeadAccountDto getDetail(int id){
        return userMapper.getDetail(id);
    }


    /**
     * 平台同意商家注册
     * @param id
     * @return
     */
    @Override
    public List<User> agreeApply(int id) {
        //1.删除申请表里的对应的申请
        userMapper.delApply(id);
        //2.激活商户状态
        userMapper.changeStatusById(id);
        //3.返回申请列表
        List<User> userList = userMapper.findApply();
        return userList;
    }


    //通过用户主id去用户角色中间表查询用户及其对应角色
    @Override
    public UserRoleMenusDto findUserRoleMenusById(int id) {
        return userMapper.findUserRoleMenusById(id);
    }

    /**
     * 修改头像
     * @param image
     * @param id
     * @return
     */
    @Override
    public Boolean changeImage(String image, int id) {
        return userMapper.changeImage(image,id)>0?true:false;
    }

    /**
     * 通过旧密码修改密码
     * @param oldpwd
     * @param newpwd
     * @return
     */
    @Override
    public Boolean updateByPwd(int id,String oldpwd, String newpwd) {
        //1.判断旧密码对不对
        //输入的旧密码加密
        oldpwd = DigestUtils.md5DigestAsHex(oldpwd.getBytes());
        //新密码加密
        newpwd = DigestUtils.md5DigestAsHex(newpwd.getBytes());
        //读取数据库中旧密码
        String temp = userMapper.findPwd(id);
        //System.out.println("oldpwd:"+oldpwd+"newpwd:"+newpwd+"temp"+temp);
        if(oldpwd.equals(temp)) {
            //2.密码相同，修改密码
            if(userMapper.updatePwd(id, newpwd)>0){
                //修改成功
                return true;
            }
        }
        return false;
    }

    /**
     * 通过用户名查询用户id
     * @param account
     * @return
     */
    @Override
    public int selectUserId(String account) {
        return userMapper.selectUserId(account);
    }

    @Override
    public List<Role> selectUserRole(Integer id) {
        return userMapper.selectUserRole(id);
    }



    /**
     * 查询用户发表的动态
     * @param id
     * @return
     */
    @Override
    public UserRecentsDto selectPublishRecent(int id) {
        return userMapper.selectPublishRecent(id);
    }

    /**
     * 查询动态作者
     * @param rid
     * @return
     */
    @Override
    public User findAuthor(int rid) {
        return userMapper.findAuthor(rid);
    }


}
